//
//  ContainsPointAndHitTestViewController.m
//  CoreAnimation
//
//  Created by 张国文 on 16/10/9.
//  Copyright © 2016年 hangzhouyijiyin. All rights reserved.
//

#import "ContainsPointAndHitTestViewController.h"

@interface ContainsPointAndHitTestViewController ()

@property (nonatomic, strong) CALayer *redLayer;
@property (nonatomic, strong) CALayer *blueLayer;

@end

@implementation ContainsPointAndHitTestViewController

//  “图层树”证实了最好使用图层相关视图，而不是创建独立的图层关系。其中一个原因就是要处理额外复杂的触摸事件。

// CALayer并不关心任何响应链事件，所以不能直接处理触摸事件或者手势。但是它有一系列的方法帮你处理事件：-containsPoint:和-hitTest:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    self.redLayer = [[CALayer alloc] init];
    self.redLayer.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3].CGColor;
  //  self.redLayer.frame = self.view.bounds;
    self.redLayer.frame = CGRectMake(150, 150, 100, 100);
    [self.view.layer addSublayer:_redLayer];
    
    self.blueLayer = [[CALayer alloc] init];
    self.blueLayer.backgroundColor = [UIColor blueColor].CGColor;
    self.blueLayer.frame = CGRectMake(100, 100, 200, 200);
    [self.view.layer addSublayer:_blueLayer];
    
     self.redLayer.zPosition = 1.0f; // 我将redLayer放在了最前面，这时点击blueLayer的区域的时候会被redLayer挡住
}


//#pragma mark - 采用containsPoint判断是点击的redLayer或者是blueLayer
////// -containsPoint:接受一个在本图层坐标系下的CGPoint，如果这个点在图层frame范围内就返回YES。也就是使用-containsPoint:方法来判断到底是红色还是蓝色的图层被触摸了 。这需要把触摸坐标转换成每个图层坐标系下的坐标，结果很不方便。
////// 重要提示：使用containsPoint要根据图层树的顺序进行调用，即底部的layer应该先调用这个方法
////
//- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
//{
//    UITouch *touch = [touches anyObject];
//    CGPoint currentPoint = [touch locationInView:self.view];
//    // 首先应该将currentPoint转化为redLayer上的point点
//    CGPoint redLayerPoint = [self.redLayer convertPoint:currentPoint fromLayer:self.view.layer];
//    if ([self.redLayer containsPoint:currentPoint]) {
//        // 说明触摸点在redLayer上
//        CGPoint blueLayerPoint = [self.blueLayer convertPoint:redLayerPoint fromLayer:self.redLayer];
//        if ([self.blueLayer containsPoint:blueLayerPoint]) {
//            // 说明触摸点在blueLayer上
//            [[[UIAlertView alloc] initWithTitle:@"提示" message:@"触摸点在blueLayer上" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil] show];
//        } else {
//             [[[UIAlertView alloc] initWithTitle:@"提示" message:@"触摸点在redLayer上" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil] show];
//        }
//    }
//}

#pragma mark - 采用hitTest方法来判断是点击redLayer或者点击blueLayer
// 注意当调用图层的-hitTest:方法时，测算的顺序严格依赖于图层树当中的图层顺序（和UIView处理事件类似）。⚠️之前提到的zPosition属性可以明显改变屏幕上图层的顺序，但不能改变事件传递的顺序。

// ⚠️这意味着如果改变了图层的z轴顺序，你会发现将不能够检测到最前方(数层结构树上位于最上面的图层)的视图点击事件，这是因为被另一个图层遮盖住了，虽然它的zPosition值较小，但是在图层树中的顺序靠前。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 这个时候blueLayer的点击事件会阻止redLayer的点击事件，及时redLayer的Zposition较高，但是blueLayer在事件传递的顺序上靠前
    CGPoint currentPoint = [[touches anyObject] locationInView:self.view];
    CALayer *clickLayer = [self.blueLayer hitTest:currentPoint];
    NSLog(@"点击了：%@", [self.blueLayer hitTest:currentPoint]);
    if (clickLayer == self.blueLayer) {
        // 说明触摸点在blueLayer上
        [[[UIAlertView alloc] initWithTitle:@"提示" message:@"触摸点在blueLayer上" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil] show];
    } else {
        // 说明触摸点在redLayer上
         [[[UIAlertView alloc] initWithTitle:@"提示" message:@"触摸点在redLayer上" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil] show];
    }

   

}

@end
